﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Configuration;

using Ivy.UserManagement.Entity;
using Ivy.SiteAdministration.Entity;

namespace FrameworkIvy.App_Code
{
    public class UserContext
    {
        #region  Variable & constant
        // All constants and local variable should be declared here
        // TRY NOT TO CREATE PUBLIC VARIABLES INSTEAD USE PROPERTIES FOR THAT PURPOSE.
        // Variable naming convention :- 
        // The naming should be self explanatory, make it long to explain the purpose 
        // and use PascalCase to seperate words as shown in the example below.
        // DO NOT USE ANY ABBRIVIATION use full word (like "Customer" instead of "Cust"
        // Naming convention for all local variable should start with underscore "_"
        // Naming convention for all local constant should start with "_The"
        // Example :    string _CustomerCode = string.Empty;
        // Example :    const string _TheDefaultSmtpServer = "DefaultSmtpServer";
        // ==================== START YOUR CODE FROM NEXT LINE ========================

        const string _TheDefaultCreatedByID = "1";
        const int _TheDefaultOrganizationID = -1;
        const string _TheDefaultCultureInfo = "en-US";
        const string _TheDefaultUserContextSessionVariableName = "UserContext";

        string lUserSessionID = string.Empty;
        string lUserIPAddress = string.Empty;
        string lUserBrowser = string.Empty;
        string lUserSessionStartTime = string.Empty;
        User lCurrentUser;
        List<UserOrganizationRole> lCurrentUserOrganizationRoles;
        Sys_OrganizationMaster lLoginSys_OrganizationMaster;
        Sys_RoleMaster lLoginSys_RoleMaster;

        string lSys_CreatedByID = _TheDefaultCreatedByID;
        Int32 lSys_OrganizationID = _TheDefaultOrganizationID;
        string lCultureInfo = _TheDefaultCultureInfo;
        bool lIsUserVerificationRequired = true;

        #endregion  Variable & constant

        #region Constructor & Destructor
        // Cut and Copy the default constructor for the class inside this region.
        // Generally not required in UI layer.
        // Example:
        // public SampleClassTemplate()
        // {

        // }
        // ==================== START YOUR CODE FROM NEXT LINE ========================


        #endregion Constructor & Destructor

        #region Properties
        // Any value/variable that needs to be exposed outside the class we need to create a property.
        // Avoid creating public variables rather create public properties.
        // UI layer may have public custom properties. these are very handy for User Controls.
        // Property naming convention :- Properties will be exposed outside the class, 
        // the naming should be self explanatory, make it long to explain the purpose 
        // and use PascalCase to seperate words as shown in the example below.
        // DO NOT USE ANY ABBRIVIATION use full word (like "Customer" instead of "Cust"
        // All properties should have a corresponding local variable 
        // and the property name and local variable name should match.
        // Example :
        // public string CustomerCode
        // {
        //     get
        //     {
        //         return _CustomerCode;
        //     }
        //     set
        //     {
        //         _CustomerCode = value;
        //     }
        // }
        // ==================== START YOUR CODE FROM NEXT LINE ========================
        public string UserSessionID
        {
            get
            {
                return lUserSessionID;
            }
            set
            {
                lUserSessionID = value;

            }
        }

        public string UserIPAddress
        {
            get
            {
                return lUserIPAddress;
            }
            set
            {
                lUserIPAddress = value;

            }
        }

        public string UserBrowser
        {
            get
            {
                return lUserBrowser;
            }
            set
            {
                lUserBrowser = value;

            }
        }

        public string UserSessionStartTime
        {
            get
            {
                return lUserSessionStartTime;
            }
            set
            {
                lUserSessionStartTime = value;

            }
        }

        public User CurrentUser
        {
            get
            {
                return lCurrentUser;
            }
            set
            {
                lCurrentUser = value;
                if (lCurrentUser != null)
                {
                    this.Sys_CreatedByID = lCurrentUser.UserPersonKey.ToString();
                    this.Sys_OrganizationID = lCurrentUser.Sys_OrganizationID; //To be changed on Society Selection if user is society member
                }
                else
                {
                    this.Sys_CreatedByID = _TheDefaultCreatedByID;
                    this.Sys_OrganizationID = _TheDefaultOrganizationID;
                }
            }
        }

        public List<UserOrganizationRole> CurrentUserOrganizationRoles
        {
            get
            {
                return lCurrentUserOrganizationRoles;
            }
            set
            {
                lCurrentUserOrganizationRoles = value;
            }
        }

        public Sys_OrganizationMaster LoginOrganization
        {
            get
            {
                return lLoginSys_OrganizationMaster;
            }
            set
            {
                lLoginSys_OrganizationMaster = value;
                if (lLoginSys_OrganizationMaster != null)
                {
                    this.Sys_OrganizationID = lLoginSys_OrganizationMaster.OrganizationID;
                }
                else
                {
                    this.Sys_OrganizationID = _TheDefaultOrganizationID;
                }
            }
        }

        public Sys_RoleMaster LoginRole
        {
            get
            {
                return lLoginSys_RoleMaster;
            }
            set
            {
                lLoginSys_RoleMaster = value;
            }
        }

        public string Sys_CreatedByID
        {
            get
            {
                return lSys_CreatedByID;
            }
            set
            {
                lSys_CreatedByID = value;

            }
        }

        public Int32 Sys_OrganizationID
        {
            get
            {
                return lSys_OrganizationID;
            }
            set
            {
                lSys_OrganizationID = value;

            }
        }

        public string CultureInfo
        {
            get
            {
                return lCultureInfo;
            }
            set
            {
                lCultureInfo = value;

            }
        }

        public bool IsUserVerificationRequired
        {
            get
            {
                return lIsUserVerificationRequired;
            }
            set
            {
                lIsUserVerificationRequired = value;
            }
        }

        #endregion Properties

        #region Events
        // Generally UI layer will have public events.
        // Cut and Copy the default generated events for the class inside this region.
        // ==================== START YOUR CODE FROM NEXT LINE ========================


        #endregion Events

        #region Public Methods
        // Any method that needs to be exposed outside the class will be created inside this region.
        // Public Method naming convention :- Public Method will be exposed outside the class, 
        // The input and output parameters are also going to be exposed outside the class
        // the naming should be self explanatory, make it long to explain the purpose 
        // and use PascalCase to seperate words as shown in the example below.
        // DO NOT USE ANY ABBRIVIATION use full word (like "Customer" instead of "Cust"
        // Example :
        // public bool RegisterNewCustomer(Customer Customer)
        // {
        //     bool IsCustomerDataSaved = false;
        //     //TO DO logic to save data
        //     IsCustomerDataSaved = InsertCustomerDataUsingDao(Customer);
        //     return IsCustomerDataSaved;
        // }
        // ==================== START YOUR CODE FROM NEXT LINE ========================


        public void ResetCurrentUser()
        {
            this.CurrentUser = null;
            this.Sys_CreatedByID = _TheDefaultCreatedByID;
            this.Sys_OrganizationID = _TheDefaultOrganizationID;
        }

        public void ResetCurrentUserOrganizationRoles()
        {
            this.CurrentUserOrganizationRoles = null;
        }

        public string GetCurrentSessionIPAddress()
        {
            //The X-Forwarded-For (XFF) HTTP header field is a de facto standard for identifying the originating IP address of a 
            //client connecting to a web server through an HTTP proxy or load balancer
            string _IPAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (string.IsNullOrEmpty(_IPAddress))
            {
                _IPAddress = HttpContext.Current.Request.UserHostAddress;
                if (string.IsNullOrEmpty(_IPAddress))
                {
                    _IPAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                }
            }
            return _IPAddress;
        }

        public string GetCurrentSessionBrowserName()
        {
            string _BrowserName = string.Empty;
            _BrowserName = HttpContext.Current.Request.Browser.Browser;
            return _BrowserName;
        }

        public string GetCurrentSessionID()
        {
            string _SessionID = string.Empty;
            _SessionID = HttpContext.Current.Session.SessionID;
            return _SessionID;
        }

        public string GetDefaultCultureInfo()
        {
            //Currently we are treating all user with same cultural info. We will change ir based of user session.
            AppSettingsReader _AppSettingsReader = new AppSettingsReader();
            string _CultureInfo = _AppSettingsReader.GetValue("CultureInfo", typeof(string)).ToString();
            return _CultureInfo;
        }

        #endregion Public Methods

        #region Private Methods
        // All local class level methods will be inside this region. Mostly these are helper methods.
        // Private Method naming convention :- The naming should be self explanatory, 
        // make it long to explain the purpose and use PascalCase to seperate words as shown in the example below.
        // DO NOT USE ANY ABBRIVIATION use full word (like "Customer" instead of "Cust"
        // Input parameter will have a "p" as prefix. 
        // This will help the parameter variable that the value is originated outside this private method.
        // Example :
        // public bool InsertCustomerDataUsingDao(Customer pCustomer)
        // {
        //     bool IsCustomerDataInsertedSuccessfully = false;
        //     //TO DO logic to save data
        //     //....
        //     //....
        //     return IsCustomerDataInsertedSuccessfully;
        // }
        // ==================== START YOUR CODE FROM NEXT LINE ========================


        #endregion Private Methods
    }
}